using System.Linq.Expressions;
using AdmissionQA.Domain.Entities;

namespace AdmissionQA.Domain.Repositorys;

/// <summary>
/// 通用数据仓库接口，定义了对实体的基本操作
/// </summary>
/// <typeparam name="T">实体类型，必须继承自 EntityBase</typeparam>
public interface IRepository<T>
    where T : EntityBase
{
    /// <summary>
    /// 异步添加一个实体
    /// </summary>
    /// <param name="entity">要添加的实体</param>
    Task CreateAsync(T entity);

    /// <summary>
    /// 批量异步添加实体
    /// </summary>
    /// <param name="entities">要添加的实体集合</param>
    Task CreateRangeAsync(IEnumerable<T> entities);

    /// <summary>
    /// 异步更新一个实体
    /// </summary>
    /// <param name="entity">要更新的实体</param>
    Task UpdateAsync(T entity);

    /// <summary>
    /// 批量异步更新实体
    /// </summary>
    /// <param name="entities">要更新的实体集合</param>
    Task UpdateRangeAsync(IEnumerable<T> entities);

    /// <summary>
    /// 根据 ID 异步获取实体
    /// </summary>
    /// <param name="id">实体的唯一标识</param>
    /// <returns>返回找到的实体，如果未找到则返回 null</returns>
    Task<T?> GetByIdAsync(Guid id);

    /// <summary>
    /// 获取所有实体（排除已删除的实体）
    /// </summary>
    /// <returns>所有未删除的实体列表</returns>
    Task<IEnumerable<T>> GetAllAsync();

    /// <summary>
    /// 分页查询实体
    /// </summary>
    /// <param name="pageIndex">当前页码，从 0 开始</param>
    /// <param name="pageSize">每页显示的记录数</param>
    /// <returns>返回分页后的数据集合</returns>
    Task<IEnumerable<T>> GetPagedAsync(int pageIndex, int pageSize);

    /// <summary>
    /// 根据条件查询实体
    /// </summary>
    /// <param name="condition">查询条件，使用表达式树构建</param>
    /// <returns>返回满足条件的数据</returns>
    Task<T?> GetOneConditionAsync(Expression<Func<T, bool>> condition);

    /// <summary>
    /// 根据条件查询实体
    /// </summary>
    /// <param name="condition">查询条件，使用表达式树构建</param>
    /// <returns>返回满足条件的数据</returns>
    Task<IEnumerable<T>> GetListConditionAsync(Expression<Func<T, bool>> condition);

    /// <summary>
    /// 获取实体总数（排除已删除的实体）
    /// </summary>
    /// <returns>实体总数</returns>
    Task<int> GetCountAsync();

    /// <summary>
    /// 根据条件获取实体数量（排除已删除的实体）
    /// </summary>
    /// <param name="condition">查询条件表达式</param>
    /// <returns>符合条件的实体数量</returns>
    Task<int> GetCountAsync(Expression<Func<T, bool>> condition);
}
